﻿/*
*作業名稱:表达式求值模拟程序
*作業完成參與人員:曹國鴻,孟秋建
*作業完成人員學號:2015015305,2015015323
*作業開始時間:2016年11月23日~2016年12月16日(初步調試完成)
*已知存在的BUG:只能進行一位數字的運算,無法進行浮點運算(能力有限了,尷尬(>﹏<。)～嗚嗚嗚……)
*編譯環境:VS 2017(主編寫環境),VS 2015(适配修改),VS 2012(适配修改失败,真心觉得就是编译器的问题,编译出来的问题没法解决)
*謝謝老師的教育,（〜^㉨^)〜
*/
#pragma once
#pragma warning(disable:4996)
#pragma warning(disable:4715)
#include<stdio.h>
#include<stdlib.h>
#include <tchar.h>

#define NEWP (ctype *)malloc(sizeof(ctype))  //定義申請棧的宏

typedef struct ty {
	char dat;
	struct ty *next;
} ctype;  //構造棧

int tance(char x);
void start();
int Calculator();


void start() {
	printf("表达式求值模拟程序\n\n");
	printf("功能菜单:\n");
	printf("===================\n");
	printf("[1]输入表达式并求值\n");
	printf("[0]退出\n");
	printf("===================\n\n");
}

int Calculator()
{
	getchar();//放空輸入流
	int rs = 0;
	ctype *s, *top;  //定義棧和棧頂指針
	int cal[50], i = 0;//定義輸入公式和變量
	char c;
	s = NEWP;
	s->dat = '@';
	s->next = NULL;
	top = s;
	c = getchar();  //一個一個讀取,直至讀取到回車字符
	while (c != '\n')
	{
		if (c >= '0'&&c <= '9')  //如果讀出數字,直接輸出數字
		{
			i++;
			cal[i] = c - 48;
		}
		else if (c == '(')  //如果檢測到左括號,壓入棧
		{
			s = NEWP;
			s->dat = c;
			s->next = top;
			top = s;
		}
		else if (c == ')')  //如果檢測到右括號,匹配左括號,並彈出棧
		{
			while (top->dat != '(')
			{
				s = top;
				if (top->dat == '+') {
					cal[i - 1] = cal[i - 1] + cal[i];
					i--;
				}
				else if (top->dat == '-') {
					cal[i - 1] = cal[i - 1] - cal[i];
					i--;
				}
				else if (top->dat == '*') {
					cal[i - 1] = cal[i - 1] * cal[i];
					i--;
				}
				else if (top->dat == '/') {
					cal[i - 1] = cal[i - 1] / cal[i];
					i--;
				}

				top = top->next;
				free(s);
			}
			s = top;
			top = top->next;
			free(s);
		}
		else  //計算+-*/運算符
		{
			int a = tance(c);
			int b = tance(top->dat);  //比較運算符號優先級
			if (a>b)  
			{
				s = NEWP;
				s->dat = c;
				s->next = top;
				top = s;
			}
			else  
			{
				while (a <= b)
				{
					s = top;
					if (top->dat == '+') {
						cal[i - 1] = cal[i - 1] + cal[i];
						i--;
					}
					else if (top->dat == '-') {
						cal[i - 1] = cal[i - 1] - cal[i];
						i--;
					}
					else if (top->dat == '*') {
						cal[i - 1] = cal[i - 1] * cal[i];
						i--;
					}
					else if (top->dat == '/') {
						cal[i - 1] = cal[i - 1] / cal[i];
						i--;
					}
					top = top->next;
					free(s);
					b = tance(top->dat);
				}
				s = NEWP;
				s->dat = c;
				s->next = top;
				top = s;
			}
		}
		c = getchar();  //讀取下一個字符串
	}
	while (top->dat != '@')  //讀完並彈出所有運算符
	{
		s = top;
		if (top->dat == '+') {
			cal[i - 1] = cal[i - 1] + cal[i];
			i--;
		}
		else if (top->dat == '-') {
			cal[i - 1] = cal[i - 1] - cal[i];
			i--;
		}
		else if (top->dat == '*') {
			cal[i - 1] = cal[i - 1] * cal[i];
			i--;
		}
		else if (top->dat == '/') {
			cal[i - 1] = cal[i - 1] / cal[i];
			i--;
		}
		top = top->next;
		free(s);
	}


	printf("%d\n", cal[1]);
	return 0;
}


int tance(char x)  //比較優先級的函數
{
	if (x == '+' || x == '-')
		return 0;
	else if (x == '*' || x == '/')
		return 1;
	else if (x == '@' || x == '(' || x == ')')
		return -1;
}
//
//void pan() {
//	s = top;
//	if (top->dat == '+') {
//		cal[i - 1] = cal[i - 1] + cal[i];
//		i--;
//	}
//	else if (top->dat == '-') {
//		cal[i - 1] = cal[i - 1] - cal[i];
//		i--;
//	}
//	else if (top->dat == '*') {
//		cal[i - 1] = cal[i - 1] * cal[i];
//		i--;
//	}
//	else if (top->dat == '/') {
//		cal[i - 1] = cal[i - 1] / cal[i];
//		i--;
//	}
//
//	top = top->next;
//	free(s);
//}